class Compiler{
  constructor(vm){
    this.el = vm.$el;
    this.vm = vm
    
    this.complie(this.el)
  }
  // 编译模板
  complie(el){
    let childNodes = el.childNodes
    Array.from(childNodes).forEach(node=>{
      if(this.isTextNode(node)){
        this.compileText(node)
      }else if(this.isElementNode(node)){
        this.compileElement(node)
      }
      

      // 判断node 节点,是否有子节点,如果有子节点,要递归调用compile
      if(node.childNodes && node.childNodes.length){
        this.complie(node)
      }
    })
  }
  // 编译元素节点
  compileElement(node){
    // console.log(node.attributes);
    
    Array.from(node.attributes).forEach(attr=>{
      let attrName = attr.name
      
      if(this.isDirective(attrName)){
        attrName = attrName.substr(2)
        
        let key = attr.value
        this.update(node,key,attrName)
      }
  
    })

  }

  update(node,key,attrName){
    
    
    let updateFn = this[attrName+"Update"]
    updateFn && updateFn.call(this,node,this.vm[key],key)
    let index=attrName.indexOf("on:")
    if(index!=-1){
      
      this.onUpdate(node,key,attrName)
      }
    
    
  }

  
onUpdate(node,value,key){
  
    
    console.log("node",node.attributes);
    console.log("value",value);
    console.log("key",key);

    console.log("---");
    // 去掉 v-on
    let clickType = key.substr(3)
    
    console.log("clickType",clickType);
   
    let objClick=  this.vm.$option.methods;
    
    node.addEventListener(clickType,objClick[value])

}
  

  // 处理 v-html 指令
  htmlUpdate(node,value,key){
    node.innerHTML = value
    new Watcher(this.vm,key,(newValue)=>{
      node.innerHTML= newValue
    })
  }

  // 处理 v-text 指令
  textUpdate(node,value,key){
    // console.log("key-1",value);
    node.textContent = value
    new Watcher(this.vm,key,(newValue)=>{
      node.textContent= newValue
    })
  }
  //处理 v-model 指令
  modelUpdate(node,value,key){
    // console.log("key-2",key);
    // console.log("222");
    // console.log("node",node.attributes);
    // console.log("value",value);
    // console.log("key",key);

    node.value = value
    new Watcher(this.vm,key,(newValue)=>{
      node.value= newValue
    })
    node.addEventListener("input",()=>{
      this.vm[key] = node.value
    })
  }
  // 编译文本节点,处理插值表达式
  compileText(node){
// console.dir(node);
    let reg = /\{\{(.+?)\}\}/
    let value = node.textContent
    if(reg.test(value)){
      let key = RegExp.$1.trim()
      node.textContent = value.replace(reg,this.vm[key])
      new Watcher(this.vm,key,(newValue)=>{
        node.textContent = newValue
      })
    }
  }
  // 判断元素属性是否是指令
  isDirective(attrname){
    return attrname.startsWith("v-")
  }
  // 判断是否是文本节点
  isTextNode(node){
    return node.nodeType === 3
  }
  // 判断是否元素节点
  isElementNode(node){
    return node.nodeType === 1
  }

}